{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit MediaImportForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, MediaRepository, pngimage;

type
  TAHMImportSteps = (isCounting, isImporting, isIndexing, isComplete);

  TfrmMediaImport = class(TForm)
    gbImportProgress: TGroupBox;
    btCancel: TButton;
    pbProgress: TProgressBar;
    txLocating: TLabel;
    txImporting: TLabel;
    txIndexing: TLabel;
    imgLocating: TImage;
    imgImporting: TImage;
    imgIndexing: TImage;
    txCounter: TLabel;
    txImporter: TLabel;
    txIndexer: TLabel;
    btOK: TButton;
    txElapsed: TLabel;
    txFinished: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure btCancelClick(Sender: TObject);
    procedure btOKClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    FFiles: Integer;
    FFolders: Integer;
    FStart: Cardinal;
    FProgress: TAHMImportSteps;
    FRepository: TAHMMediaRepository;
    FCancelled: Boolean;
    FCompleted: Boolean;
    procedure ImportCallback(Files, Folders, Failed: Integer; Complete: Boolean);
    procedure UpdateProgress(Progress: TAHMImportSteps);
    procedure LoadImages;
  public
    { Public declarations }
    class function ImportMedia(Repository: TAHMMediaRepository; AutoClose: Boolean = True): Boolean;
    function Import(Repository: TAHMMediaRepository; AutoClose: Boolean): Boolean;
  end;


implementation

{$R *.dfm}

uses MMSystem, Utilities;

class function TfrmMediaImport.ImportMedia(Repository: TAHMMediaRepository; AutoClose: Boolean): Boolean;
begin
  with TfrmMediaImport.Create(Application.MainForm) do
  try
    PopupParent := Application.MainForm;
    Result := Import(Repository, AutoClose);
  finally
    Free;
  end;
end;

function TfrmMediaImport.Import(Repository: TAHMMediaRepository; AutoClose: Boolean): Boolean;
begin
  // Set default result - import failed/aborted
  Result := False;

  // Hook up import callback & record start time
  FRepository := Repository;
  Repository.Callback := ImportCallback;
  FStart := timeGetTime;

  // Show form and wait for paint
  btOK.Visible := not AutoClose;
  Show;
  Application.ProcessMessages;

  // Step 1: scan media files
  FRepository.CountMedia;
  if FCancelled then Exit;
  FRepository.WaitForCompletion;
  if FCancelled then Exit;

  // Step 2: import media files
  FRepository.ScanMedia;
  if FCancelled then Exit;
  FRepository.WaitForCompletion;
  if FCancelled then Exit;

  // Step 3: index media files
  FRepository.IndexMedia;
  if FCancelled then Exit;
  FRepository.WaitForCompletion;
  if FCancelled then Exit;

  // If we want to autoclose then just show form briefly...
  if AutoClose then
    Sleep(500)
  else
  begin
    // ...otherwise wait for explicit ok/cancel
    btOK.Enabled := True;
    btOK.SetFocus;
    while not (FCompleted or FCancelled) do
      Application.HandleMessage;
  end;

  Result := not FCancelled;
end;

procedure TfrmMediaImport.FormCreate(Sender: TObject);
begin
  // Load and replicate images
  LoadImages;

  // Initialise status stuff
  UpdateProgress(isCounting);
end;

procedure TfrmMediaImport.FormDestroy(Sender: TObject);
begin
  // Ensure cursor is restored
  Screen.Cursor := crDefault;
end;

procedure TfrmMediaImport.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  // Abandon media import if not yet completed, otherwise complete
  if btOK.Visible then
    FCompleted := True
  else
  begin
    FCancelled := True;
    FRepository.Abort;
  end;
end;

procedure TfrmMediaImport.btOKClick(Sender: TObject);
begin
  // Set flag to close form
  FCompleted := True;
end;

procedure TfrmMediaImport.btCancelClick(Sender: TObject);
begin
  // Abandon media import
  FCancelled := True;
  FRepository.Abort;
end;

procedure TfrmMediaImport.ImportCallback(Files, Folders, Failed: Integer; Complete: Boolean);
var
  Elapsed: String;
begin
  case FProgress of
    isCounting:
    begin
      FFiles := Files;
      txCounter.Caption := Format('%d files found', [Files]);

      if Complete then UpdateProgress(isImporting);
    end;
    isImporting:
    begin
      FFolders := Folders;
      txImporter.Caption := Format('%d files imported', [Files + Failed]);
      pbProgress.Position := Files + Failed;

      if Complete then UpdateProgress(isIndexing);
    end;
    isIndexing:
    begin
      txIndexer.Caption := Format('%d albums indexed', [Folders]);
      pbProgress.Position := Folders;

      if Complete then UpdateProgress(isComplete);
    end;
  end;

  // Update elapsed time
  Elapsed := DurationToString(timeGetTime - FStart);
  if Elapsed <> '' then txElapsed.Caption := 'Elapsed time: ' + Elapsed;

  // Update UI etc.
  Application.ProcessMessages;
end;

procedure TfrmMediaImport.UpdateProgress(Progress: TAHMImportSteps);
begin
  case Progress of
    isCounting:
    begin
      Screen.Cursor := crHourglass;
      txLocating.Font.Style := [fsBold];
      txImporting.Font.Style := [];
      txIndexing.Font.Style := [];
      txFinished.Visible := False;
      imgLocating.Visible := False;
      imgImporting.Visible := False;
      imgIndexing.Visible := False;
      txCounter.Caption := '';
      txImporter.Caption := '';
      txIndexer.Caption := '';
      txElapsed.Caption := '';
      pbProgress.Position := 0;
    end;
    isImporting:
    begin
      txLocating.Font.Style := [];
      txImporting.Font.Style := [fsBold];
      imgLocating.Visible := True;
      pbProgress.Max := FFiles;
    end;
    isIndexing:
    begin
      txImporting.Font.Style := [];
      txIndexing.Font.Style := [fsBold];
      imgImporting.Visible := True;
      pbProgress.Max := FFolders;
    end;
    isComplete:
    begin
      txIndexing.Font.Style := [];
      txFinished.Visible := True;
      imgIndexing.Visible := True;
      Screen.Cursor := crDefault;
    end;
  end;

  // Record new progress state
  FProgress := Progress;

  // Allow form to update with changes
  Application.ProcessMessages;
end;

procedure TfrmMediaImport.LoadImages;
var
  TempImage: TPNGObject;
begin
  // Use temporary PNG image to load from resource
  TempImage := TPNGObject.Create;
  try
    TempImage.LoadFromResourceName(hInstance, 'SM_IMG_TICK');

    imgLocating.Picture.Graphic := TempImage;
    imgImporting.Picture.Graphic := TempImage;
    imgIndexing.Picture.Graphic := TempImage;
  finally
    TempImage.Free;
  end;
end;


end.
